package demo.ui;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferStrategy;
import java.util.Timer;
import java.util.TimerTask;

public class StrategyCanvas extends Canvas implements MouseListener{
	private BufferStrategy		strategy;
	private final Timer			timer;
	private TimerTask			renderTask;
	private Paint				backgroundGradient;
	
	private AffineTransform transform = new AffineTransform();
	
	private Tank tank1, tank2; 
	
	static {
		//System.setProperty("sun.java2d.trace", "timestamp,log,count");
		//System.setProperty("sun.java2d.transaccel", "True");
		//System.setProperty("sun.java2d.opengl", "True");
		// System.setProperty("sun.java2d.d3d", "false"); //default on windows
		// System.setProperty("sun.java2d.ddforcevram", "true");
	}
	
	public StrategyCanvas(){
		this.setIgnoreRepaint(true);
		timer = new Timer(); // used for the render thread
		tank1 = new Tank();
		tank1.x = 200;
		tank1.y = 150;
		tank1.setDirection(2.22f);
		tank1.setSpeed(20);
		
		tank2 = new Tank();
		tank2.x = 120;
		tank2.y = 110;
		tank2.setDirection(1.3f);
		tank2.setSpeed(90);
		
		addMouseListener(this);
		setPreferredSize(new Dimension(700, 350));
	}
	
	public void render(){
		Graphics2D g2 = (Graphics2D)strategy.getDrawGraphics();
		g2.setPaint(backgroundGradient);
		g2.fillRect(0, 0, getWidth(), getHeight());

		// TODO: Draw your game world, or scene or anything else here.
		tank1.draw(g2, transform);
		tank2.draw(g2, transform);
		// Rectangle2D is a shape subclass, and the graphics object can render
		// it, makes things a little easier.
		g2.setColor(Color.green.darker());
		//g2.fill(basicBlock);

		// properly dispose of the backbuffer graphics object. Release resources
		// and cleanup.
		g2.dispose();

		// flip/draw the backbuffer to the canvas component.
		strategy.show();

		// synchronize with the display refresh rate.
		Toolkit.getDefaultToolkit().sync();
	}
	
	public void setup() {
		// create the block, as a basic paddle
		//basicBlock = new Rectangle2D.Double(0, 0, 128, 16);

		// center the block in the canvas.
		//basicBlock.x = this.getWidth() / 2 - basicBlock.width / 2;

		// put the block at the bottom of the canvas
		//basicBlock.y = this.getHeight() - basicBlock.height - 20;

		// create the background gradient paint object.
		backgroundGradient = new GradientPaint(0, 0, Color.gray, getWidth(),
				getHeight(), Color.lightGray.brighter());

		// create a strategy that uses two buffers, or is double buffered.
		this.createBufferStrategy(2);

		// get a reference to the strategy object, for use in our render method
		// this isn't necessary but it eliminates a call during rendering.
		strategy = this.getBufferStrategy();

		start();
	}
	
	/**
	 * Initialize the render and update tasks, to call the render method, do
	 * timing and FPS counting, handling input and canceling existing tasks.
	 */
	public void start() {
		// if the render task is already running stop it, this may cause an
		// exception to be thrown if the task is already canceled.
		if (renderTask != null) {
			renderTask.cancel();
		}

		// our main task for handling the rendering and for updating and
		// handling input and movement events. The timer class isn't the most
		// reliable for game updating and rendering but it will suffice for the
		// purpose of this snippet.
		renderTask = new TimerTask() {
			long	lasttime	= System.currentTimeMillis();

			@Override
			public void run() {

				// get the current system time
				long time = System.currentTimeMillis();

				// calculate the time passed in milliseconds
				double dt = (time - lasttime) * 0.001;

				// save the current time
				lasttime = time;

				/*
				// for now just move the basic block
				if (right) {
					basicBlock.x += dt * speed;
				} else if (left) {
					basicBlock.x -= dt * speed;
				}
				*/

				render();
			}
		};

		// These will cap our frame rate but give us unexpected results if our
		// rendering or updates take longer than the 'period' time. It
		// is likely that we could have overlapping calls.
		//timer.schedule(renderTask, 0, 16);
		timer.schedule(renderTask, 0, 33);
	}

	/**
	 * Stops the rendering cycle so that the application can close gracefully.
	 */
	protected void stop() {
		renderTask.cancel();
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		try {
			if(!tank1.isMoving())
				tank1.startMove();
			else
				tank1.stop();
			
			if(!tank2.isMoving())
				tank2.startMove();
			else
				tank2.stop();
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}
